MatchTeaser.tsx ➔ getData   D
last analyzed

Complexity

Conditions 12

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 5
rs 4.8
c 0
b 0
f 0
cc 12

How to fix   Complexity   

Complexity

Complex classes like MatchTeaser.tsx ➔ getData often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
import { Match } from "../Types/Match"
2
import { MatchTeaserDetailProps, MatchTeaserProps, MatchTeasersProps } from "../Types/MatchTeaser"
3
import { useSiteMetaData } from "../hooks/use-site-metadata"
4
import { mapPsdStatus, request } from "../scripts/helper"
5
import "./MatchTeaser.scss"
6
import classNames from "classnames"
7
import { DateTime, Settings } from "luxon"
8
import React, { useEffect, useState } from "react"
9
import LazyLoad from "react-lazy-load"
10
import MiniRanking from "./MiniRanking"
11
12
export const MatchTeaserDetail = ({ match, includeRankings }: MatchTeaserDetailProps) => {
13
  Settings.defaultZone = `Europe/Brussels`
14
  Settings.defaultLocale = `nl-be`
15
16
  const matchDateTime = DateTime.fromFormat(match.date, `yyyy-MM-dd HH:mm`)
17
  const matchPlayed =
18
    ((match.status === 0 || match.status === null) && match.goalsHomeTeam !== null && match.goalsAwayTeam !== null) ||
19
    false
20
21
  return (
22
    <article className="match__teaser">
23
      <header>
24
        <h3>{match.teamName.replace(`Voetbal : `, ``)}</h3>
25
        {match.status !== 0 && (
26
          <div className="match__teaser__datetime__wrapper match__teaser__datetime__wrapper--status">
27
            <time
28
              className="match__teaser__datetime match__teaser__datetime--date"
29
              dateTime={matchDateTime.toFormat(`yyyy-MM-dd - H:mm`)}
30
            >
31
              {matchDateTime.toFormat(`EEEE dd LLLL - H:mm`)}
32
            </time>
33
            <span className="match__teaser__datetime match__teaser__datetime--status">
34
              {mapPsdStatus(match.status)}
35
            </span>
36
          </div>
37
        )}
38
        {(match.status === 0 || match.status === null) && (
39
          <div className="match__teaser__datetime__wrapper">
40
            <time
41
              className="match__teaser__datetime match__teaser__datetime--date"
42
              dateTime={matchDateTime.toFormat(`yyyy-MM-dd`)}
43
            >
44
              {matchDateTime.toFormat(`EEEE dd LLLL`)}
45
            </time>
46
            {` `}-{` `}
47
            <time
48
              className="match__teaser__datetime match__teaser__datetime--time"
49
              dateTime={matchDateTime.toFormat(`H:mm`)}
50
            >
51
              {matchDateTime.toFormat(`H:mm`)}
52
            </time>
53
          </div>
54
        )}
55
      </header>
56
      <main>
57
        <div
58
          className={classNames(`match__teaser__team`, `match__teaser__team--home`, {
59
            "match__teaser__team--winner": matchPlayed && match.goalsHomeTeam > match.goalsAwayTeam,
60
          })}
61
        >
62
          <LazyLoad>
63
            <img
64
              src={match.homeClub?.logo}
65
              alt={match.homeClub?.abbreviation}
66
              className="match__teaser__logo match__teaser__logo--home"
67
            />
68
          </LazyLoad>
69
          {match.homeClub?.abbreviation || match.homeClub?.name}
70
        </div>
71
72
        {matchPlayed || <span className="match__teaser__vs">vs</span>}
73
        {matchPlayed && (
74
          <div className="match__teaser__vs match__teaser__vs--score">
75
            <div className="match__teaser__vs--score--home">{match.goalsHomeTeam}</div>-
76
            <div className="match__teaser__vs--score--away">{match.goalsAwayTeam}</div>
77
          </div>
78
        )}
79
80
        <div
81
          className={classNames(`match__teaser__team`, `match__teaser__team--away`, {
82
            "match__teaser__team--winner": matchPlayed && match.goalsHomeTeam < match.goalsAwayTeam,
83
          })}
84
        >
85
          <LazyLoad>
86
            <img
87
              src={match.awayClub?.logo}
88
              alt={match.awayClub?.abbreviation}
89
              className="match__teaser__logo match__teaser__logo--away"
90
            />
91
          </LazyLoad>
92
          {match.awayClub?.abbreviation || match.awayClub?.name}
93
        </div>
94
      </main>
95
      {includeRankings && match.competitionType === `Competitie` && (
96
        <MiniRanking
97
          teamId={match.homeTeamId || match.awayTeamId}
98
          homeTeam={match.homeClub?.name}
99
          awayTeam={match.awayClub?.name}
100
        />
101
      )}
102
    </article>
103
  )
104
}
105
106
export const MatchTeaser = ({ teamId, action, includeRankings }: MatchTeaserProps) => {
107
  if (action !== `prev` && action !== `next`) {
108
    throw new Error(`Invalid action provided`)
109
  }
110
111
  const [data, setData] = useState<Match[]>([])
112
113
  const { kcvvPsdApi } = useSiteMetaData()
114
115
  useEffect(() => {
116
    async function getData() {
117
      const response = await request.get(`${kcvvPsdApi}/matches/${action}`, {
118
        params: { include: teamId },
119
      })
120
      setData(response.data)
121
    }
122
    getData()
123
  }, [action, kcvvPsdApi, teamId])
124
125
  if (data.length > 0) {
126
    return <MatchTeaserDetail match={data[0]} includeRankings={includeRankings} />
127
  } else {
128
    return <div className="match__teaser__no_match">Geen wedstrijd gevonden</div>
129
  }
130
}
131
132
export const MatchTeasers = ({ teamId, includeRankings = false }: MatchTeasersProps) => (
133
  <div className="match__teasers__wrapper full-width">
134
    <div className="match__teasers__inner">
135
      <div className="match__teasers match__teasers--prev">
136
        <header className="match__teasers__header">Vorige</header>
137
        <MatchTeaser teamId={teamId} action="prev" includeRankings={includeRankings} />
138
      </div>
139
      <div className="match__teasers match__teasers--next">
140
        <header className="match__teasers__header">Volgende</header>
141
        <MatchTeaser teamId={teamId} action="next" includeRankings={includeRankings} />
142
      </div>
143
    </div>
144
  </div>
145
)
146
147
MatchTeaser.defaultProps = { includeRankings: false }
148
MatchTeasers.defaultProps = { includeRankings: false }
149
MatchTeaserDetail.defaultProps = { includeRankings: false }
150